import importlib
import inspect
import sys
from pathlib import Path
from typing import Optional
from typing import Type

from lagom import Container, Singleton

from core.engine import EventEngine, EVENT_TIMER, Event


class AppContext:
    def __init__(self):
        self.container = Container()
        self.engine = EventEngine()

    @staticmethod
    def get_app_context():
        return app

    def scan_and_register(self, package_path: str, base_package: Optional[str] = None):
        """
        扫描目录并自动注册用 @magic_bind_to_container 装饰的类
        :param package_path: 要扫描的目录路径（相对/绝对）
        :param base_package: 基础包名（如 'app.plugins'），若为None则使用相对导入
        """
        abs_path = Path(package_path).resolve() if not Path(package_path).is_absolute() \
            else Path(package_path)

        # 确保扫描目录的父目录在Python路径中
        parent_path = str(abs_path.parent)
        if parent_path not in sys.path:
            sys.path.insert(0, parent_path)

        for py_file in abs_path.rglob("*.py"):
            if py_file.name.startswith("_"):
                continue

            # 构建模块导入路径
            rel_path = py_file.relative_to(abs_path.parent)
            module_path_parts = rel_path.with_suffix('').parts
            module_path = f"{base_package}.{'.'.join(module_path_parts)}" if base_package \
                else '.'.join(module_path_parts)

            try:
                module = importlib.import_module(module_path)
                self._register_magic_classes(module)
            except ImportError as e:
                print(f"[Lagom] 导入失败 {module_path}: {str(e)}")
                continue
            except Exception as e:
                print(f"[Lagom] 注册异常 {module_path}: {str(e)}")
                continue

    def _register_magic_classes(self, module):
        """注册模块中用 @magic_bind_to_container 装饰的类"""
        for _, cls in inspect.getmembers(
                module,
                predicate=lambda x: inspect.isclass(x)):
            try:
                if not hasattr(cls, 'xin_cls'):
                    continue
                is_single = getattr(cls, 'xin_cls', False)
                # 通过容器解析触发实例化（依赖会自动注入）
                if is_single:
                    self.container[cls] = Singleton(cls)
                    # 注册其中的定时器
                    ins = self.container[cls]
                    if getattr(ins, 'update'):
                        self.engine.register(EVENT_TIMER, ins.update)
                else:
                    self.container[cls] = cls
                print(f"[Lagom] 已注册 {cls.__module__}.{cls.__name__}")
            except Exception as e:
                print(f"[Lagom] 实例化失败 {cls.__name__}: {str(e)}")

    def get(self, cls: Type):
        """获取实例（兼容Lagom原生语法）"""
        return self.container[cls]


app = AppContext()
app.scan_and_register("../plugins")

# x = AppContext.get_app()
# print()
